package ui;

import java.awt.BorderLayout;
import parser.XYZParserTreeConstants;
import java.awt.Color;
import java.awt.Container;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.StringBufferInputStream;
import java.util.HashMap;
import java.util.Iterator;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextPane;
import javax.swing.JTree;

//import debug.DebugPrint;

//import entity.References;


import parser.ParseException;
import parser.SimpleNode;
import parser.XYZParser;
//import parser2.XYZParserTreeConstants;
import stat.Lexical;
import stat.StmtAnalysis;
public class ui implements ActionListener{
	private JFrame frame;
	private Container contentPane;
	
	private TextArea text;
	private TextArea area;
	private JButton button_1;
	private JTree tree;
	public ui () {
	frame = new JFrame();
	frame.setBounds(200, 100, 750, 600);
	contentPane = frame.getContentPane();
	init();
	
	System.setOut(new GUIPrintStream(System.out, area));
	System.setErr(new GUIPrintStream(System.out, area));
	}

	private HashMap<String, String> idmap;
	
	private void add(String identify, String type) {
		this.idmap.put(identify, type);
	}

	public void init(){
		  tree=new JTree();
		  JScrollPane scrollPane=new JScrollPane();
		  scrollPane.setViewportView(tree);
	
		
		
		JMenuItem menuItem1 = new JMenuItem("Open");
		JMenuItem menuItem2 = new JMenuItem("New");
		JMenuItem menuItem3 = new JMenuItem("Exit");
		JMenuItem menuItem4 = new JMenuItem("Lexical Analysis");
		JMenuItem menuItem5 = new JMenuItem("Grammar Analysis");
		JMenuItem menuItem6 = new JMenuItem("Semantic Analysis");
		JMenuItem menuItem7 = new JMenuItem("Address Translate");
		JMenuItem menuItem8 = new JMenuItem("Symbol Table");
		
		  menuItem1.addActionListener(this);
		  menuItem2.addActionListener(this);
		  menuItem3.addActionListener(this);
		  menuItem4.addActionListener(this);
		  menuItem5.addActionListener(this);
		  menuItem6.addActionListener(this);
		  menuItem7.addActionListener(this);
		  menuItem8.addActionListener(this);
		  JMenu menu1 = new JMenu("File");
		  JMenu menu2 = new JMenu("Compile");  
		  menu1.add(menuItem1);
		  menu1.add(menuItem2);
		  menu1.add(menuItem3);
		  menu2.add(menuItem4);
		  menu2.add(menuItem5);
		  menu2.add(menuItem6);
		  menu2.add(menuItem7);
		  menu2.add(menuItem8);
		  JMenuBar menubar = new JMenuBar();
		  menubar.add(menu1);
		  menubar.add(menu2);
		  frame.setJMenuBar(menubar);
		//  contentPane.add(menu,BorderLayout.SOUTH);
		  
		   JPanel jp1 = new JPanel();
		   jp1.setLayout(new BorderLayout());
		   jp1.add(scrollPane);
		JPanel jp2 = new JPanel();
		text = new TextArea(18,70);
		area = new TextArea(15,70);
		text.setBackground(Color.white);
		area.setBackground(Color.white);
		jp2.setBounds(200, 200, 500, 500);
		jp2.setLayout(new BorderLayout());
		jp2.add(text,BorderLayout.NORTH);
		jp2.add(area,BorderLayout.SOUTH);
	
	
		contentPane.setLayout(new BorderLayout());
		contentPane.add(jp1);
		contentPane.add(jp2,BorderLayout.EAST);
		/*contentPane.add(scrollPane,BorderLayout.WEST);
		text = new TextArea(10,10);
		contentPane.add(text,BorderLayout.EAST);
		area = new TextArea(10,10);
		contentPane.add(area,BorderLayout.SOUTH);
		
		button_1 = new JButton("Compile");
		button_1.addActionListener(this);
		//contentPane.add(button_1,BorderLayout.SOUTH);
		
		*/
	}
	
	public void actionPerformed(ActionEvent e) {
	   // textField.setText("");
	    //textField.setText(button.getActionCommand());
		XYZParser parser = new XYZParser(new StringBufferInputStream(text.getText()));
		
		if(e.getActionCommand().equals("Lexical Analysis")) {
			try {
				Lexical lex = new Lexical();
				parser.ReInit(new StringBufferInputStream(text.getText()));
				lex.getTokenStream(parser);
				parser.ReInit(new StringBufferInputStream(text.getText()));
				lex.getTokenAnalysis(parser);
			}catch (Exception e2) {
				System.out.println(e2.getMessage());
			}
		}
		if(e.getActionCommand().equals("Grammar Analysis")) {
			SimpleNode sn;
			try {
				sn = parser.Start();
	//			sn.dump("");
				StmtAnalysis ss = new StmtAnalysis();
				tree.setModel(ss.getTreeModel(sn));
				
				//System out count
				int weight = ss.countStatements(sn);
				System.out.println("\n\nGrammar Analysis:");
				System.out.println("Tree wight:\t"+weight);
				System.out.println("Print Statement:\t"+ss.getPrintCount());
				System.out.println("Assignment Statement:\t"+ss.getAssignmentCount());
				System.out.println("ArrayAssignment Statement:\t"+ss.getArrayAssignmentCount());
				System.out.println("Return Statement:\t"+ss.getReturnCount());
			} catch (ParseException e1) {
				// TODO Auto-generated catch block
				System.out.println(e1.getMessage());
			}
		}
		if(e.getActionCommand().equals("Semantic Analysis")){
			try {
				XYZParser parser2 = new XYZParser(new StringBufferInputStream(text.getText()));
				SimpleNode sn = parser2.Start();
				
				this.idmap = new HashMap<String, String>();
				this.visit(sn);
				
				Iterator<String> iter = this.idmap.keySet().iterator();
				String key, outText = "";
				
				while (iter.hasNext()) {
					key = iter.next();
					outText += key + "\t" + this.idmap.get(key) + "\n";
				}
				
				while (sn.getId() != XYZParserTreeConstants.JJTSTART)
					sn = (SimpleNode)sn.jjtGetParent();
				stat.TypeChecking tc = new stat.TypeChecking(sn);
				tc.Check();
				
				outText += tc.getErrorMessage();
				area.setText(outText);
			}
			catch (Exception err) {
				//DebugPrint.getInstance().show(err.getLocalizedMessage(), DebugPrint.GUI_OUT);
				System.out.println(err.getLocalizedMessage());
			}
		}
		
		if(e.getActionCommand().equals("Address Translate")){				
			try {
				XYZParser parser2 = new XYZParser(new StringBufferInputStream(text.getText()));
				SimpleNode sn = parser2.Start();
				
				this.idmap = new HashMap<String, String>();
				this.visit(sn);
				
			//	Iterator<String> iter = this.idmap.keySet().iterator();
				String  outText = "";
				
				while (sn.getId() != XYZParserTreeConstants.JJTSTART)
					sn = (SimpleNode)sn.jjtGetParent();

				stat.AddrTranslate ad = new stat.AddrTranslate(sn);
				ad.translate();
				outText += ad.getResult();
				area.setText(outText);
			}
			catch (Exception err) {
				System.out.println(err.getLocalizedMessage());
			}
		}
		
		if(e.getActionCommand().equals("Symbol Table")){				
			try {
				XYZParser parser2 = new XYZParser(new StringBufferInputStream(text.getText()));
				SimpleNode sn = parser2.Start();
				
				this.idmap = new HashMap<String, String>();
				this.visit(sn);
				
				String  outText = "";
				
				while (sn.getId() != XYZParserTreeConstants.JJTSTART)
					sn = (SimpleNode)sn.jjtGetParent();

				stat.SymbolTable ad = new stat.SymbolTable(sn) ;
				ad.symbolize();
				outText += ad.printTable();
				area.setText(outText);
			}
			catch (Exception err) {
				System.out.println(err.getLocalizedMessage());
			}
		}
		
	}
	
	public void go(){
		frame.setVisible(true);
	}
	
	private void visit(SimpleNode root) {
		String identify, type;
		SimpleNode typeNode;
		switch (root.getId()) {
		case XYZParserTreeConstants.JJTMAINCLASS:
		case XYZParserTreeConstants.JJTCLASSDECL:
			identify = ((SimpleNode)root.jjtGetChild(0)).jjtGetFirstToken().toString();
			type = "class";
			this.add(identify, type);
			break;
		case XYZParserTreeConstants.JJTVARDECL:
			identify = ((SimpleNode)root.jjtGetChild(1)).jjtGetFirstToken().toString();
			typeNode = (SimpleNode)root.jjtGetChild(0).jjtGetChild(0);
			if (typeNode.getId() == XYZParserTreeConstants.JJTIDENTIFIER)
				type = typeNode.jjtGetFirstToken().toString();
			else
				type = XYZParserTreeConstants.jjtNodeName[typeNode.getId()];
			this.add(identify, type);
			break;
		}

		for (int i = 0; i < root.jjtGetNumChildren(); ++i)
			visit((SimpleNode)root.jjtGetChild(i));
	}
	
}